package glemipsc;

import java_cup.runtime.*;

%%

/* JFlex produrra' in uscita una classe dal nome Lexer.class */
%class Lexer
%cup
%line
%column

/* Definizione delle costanti */
sign_modifier_token    = signed|unsigned
type_token             = int|long|short|float|double|char
leng_modifier_token    = long|short
storage_spec_token     = extern|register|auto|static
void_token             = void
ws                     = [ \t]+
const                  = ('+'|'-')?[0-9]+
floating    	     = ('+'|'-')?(([0-9]+'.'[0-9]*)|([0-9]*'.'[0-9]+))(e|E('+'|'-')?[0-9]+)?
stringa                = \"([^\n\r\"]+|\\\")*\"
identificatore         = [A-Za-z_][A-Za-z0-9_]*
relop                  = ("=="|">="|"<="|"<"|">"|"!=")
assop                  = ("+="|"-="|"*="|"/="|"%="|"&="|"^="|"|="|"<<="|">>=")
shiftop                = ("<<"|">>")
charconst              = \'.\'

%{
   private Symbol symb(int type){
         return new Symbol(type, yyline, yycolumn);
  }
   private Symbol symb(int type, Object value){       //Per la gestione semantica
         return new Symbol(type, yyline,yycolumn,value);
  }
%}

%%

{ws}                 {;}
\n | \r | \r\n       {;}

if                    {return symb(sym.IF); }
else                  {return symb(sym.ELSE); }
while                 {return symb(sym.WHILE); }
do                    {return symb(sym.DO); }
switch                {return symb(sym.SWITCH); }
case                  {return symb(sym.CASE); }
break                 {return symb(sym.BREAK, yytext()); }
continue              {return symb(sym.CONTINUE, yytext()); }
for                   {return symb(sym.FOR); }
return                {return symb(sym.RETURN); }
default               {return symb(sym.DEFAULT); }
"++"                  {return symb(sym.INCR); }
"--"                  {return symb(sym.DECR); }
{assop}               {return symb(sym.ASSOP, yytext()); }
{relop}               {return symb(sym.RELOP, yytext()); }
"&&"                  {return symb(sym.AND); }
"||"                  {return symb(sym.OR); }

"+"                    {return symb(sym.PLUS); }
"-"                    {return symb(sym.MINUS); }
"*"                    {return symb(sym.TIMES); }
"/"                    {return symb(sym.DIVIDE); }
"%"                    {return symb(sym.MOD); }
"="                    {return symb(sym.UGUALE); }

"("                    {return symb(sym.TONDAOPEN); }
")"                    {return symb(sym.TONDACLOSED); }
"["                    {return symb(sym.QUADRAOPEN); }
"]"                    {return symb(sym.QUADRACLOSED); }
"{"                    {return symb(sym.GRAFFAOPEN); }
"}"                    {return symb(sym.GRAFFACLOSED); }


";"                    {return symb(sym.PUNTOEVIRGOLA); }
","                    {return symb(sym.VIRGOLA); }
":"                    {return symb(sym.DUEPUNTI); }
"!"                    {return symb(sym.NOT); }
{shiftop}              {return symb(sym.SHIFTOP, yytext()); }
"~"                    {return symb(sym.BITNOT); }
"^"                    {return symb(sym.BITXOR); }
"|"                    {return symb(sym.BITOR); }
"&"                    {return symb(sym.BITAND); }
"?"                    {return symb(sym.PUNTOINTERROGATIVO); }

{charconst}           {return symb(sym.CHARCONST, ""+yytext().charAt(1)); }
{sign_modifier_token} {return symb(sym.SIGN_MODIFIER, yytext()); }
{leng_modifier_token} {return symb(sym.LENG_MODIFIER, yytext()); }
{storage_spec_token}  {return symb(sym.STORAGE_SPEC, yytext()); }
{type_token}          {return symb(sym.TYPE, yytext()); }
{void_token}          {return symb(sym.VOID); }
{stringa}             {return symb(sym.STRINGCONST, yytext());}
{const}|{floating}    {return symb(sym.CONST, yytext());}

"sizeof"              {return symb(sym.SIZEOF); }

{identificatore}      {return symb(sym.ID, yytext());
/* Si ricorda che questa regola deve comparire dopo le
altre regole, in particolare quelle relative alle parole
chiave, altrimenti a causa delle regole di risoluzione
delle ambiguita' tutte le keyword verrebbero erroneamente
riconosciute come identificatori */}
